Skip to content

[CORRUPTED] Synthetic Benchmark PR #24640 - fix: allow org admin to cancel and reschedule seated bookings#22

Closed
tomerqodo wants to merge 33 commits into
base_pr_24640_20251106_1955from
corrupted_pr_24640_20251106_1955
Closed

[CORRUPTED] Synthetic Benchmark PR #24640 - fix: allow org admin to cancel and reschedule seated bookings#22
tomerqodo wants to merge 33 commits into
base_pr_24640_20251106_1955from
corrupted_pr_24640_20251106_1955

Conversation

@tomerqodo

Copy link
Copy Markdown

Benchmark PR calcom#24640

Type: Corrupted (contains bugs)

Original PR Title: fix: allow org admin to cancel and reschedule seated bookings
Original PR Description: ## What does this PR do?

  • Fixes #XXXX (GitHub issue number)
  • Fixes CAL-XXXX (Linear issue number - should be visible at the bottom of the GitHub issue description)

Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).

Video Demo (if applicable):

  • Show screen recordings of the issue or feature.
  • Demonstrate how to reproduce the issue, the behavior before and after the change.

Image Demo (if applicable):

  • Add side-by-side screenshots of the original and updated change.
  • Highlight any significant change(s).

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Are there environment variables that should be set?
  • What are the minimal test data to have?
  • What is expected (happy path) to have (input and output)?
  • Any other important info that could help to test that PR

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

Summary by cubic

Allow org admins and owners to reschedule and cancel seated bookings for users in their org and sub-teams. Centralized the org admin check and fixed the confirmation message text.

  • Bug Fixes

    • Permit cancellation and rescheduling when the requester is an org admin/owner of the booking host.
    • Return the correct "seatUid required" error for seated bookings unless an org admin reschedules all seats.
    • Correct confirmation message to "Booking confirmed"/"Booking rejected".
  • Refactors

    • Moved org admin logic to PrismaOrgMembershipRepository and reused across API/TRPC.
    • Simplified reschedule flow to detect individual-seat vs org-admin all-seat requests.

Written for commit 202d468. Summary will update automatically on new commits.

Original PR URL: calcom#24640

Issues Breakdown

  • Total Issues: 8
  • Easy: 3
  • Medium: 3
  • Hard: 2

Ryukemeister and others added 30 commits October 22, 2025 17:51
- Add seated event type creation for testing
- Add test for org admin rescheduling a seated booking for a managed user
- Add test for org admin canceling a full seated booking for a managed user
- Add test for org admin canceling a specific seat in a seated booking

These tests verify the functionality added in PR calcom#24640 which allows
org admins to reschedule and cancel seated bookings for users in their
organization.

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
Move canRescheduleBooking call to happen after input validation
(including seatUid validation for seated bookings) but before the
actual booking creation. This ensures that when trying to reschedule
a seated booking without providing seatUid, users get the proper
'seatUid required' error instead of 'booking has been cancelled' error.

Fixes failing e2e test: 'should not be able to reschedule seated
booking if seatUid is not provided'

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>
@tomerqodo

tomerqodo commented Nov 11, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


⚠️ Analysis Unavailable

We ran into an issue on our side and couldn’t complete the review right now

1 similar comment
@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


⚠️ Analysis Unavailable

We ran into an issue on our side and couldn’t complete the review right now

@tomerqodo

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Come back soon, analysis in progress

1 similar comment
@tomerqodo

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Come back soon, analysis in progress

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


⚠️ Analysis Unavailable

We ran into an issue on our side and couldn’t complete the review right now

@tomerqodo

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Come back soon, analysis in progress

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


⚠️ Analysis Unavailable

We ran into an issue on our side and couldn’t complete the review right now

@tomerqodo

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Come back soon, analysis in progress

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


⚠️ Analysis Unavailable

We ran into an issue on our side and couldn’t complete the review right now

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


No Issues Found

Qodo reviewed your code and found no material issues that require review.

@tomerqodo

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Come back soon, analysis in progress

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


No Issues Found

Qodo reviewed your code and found no material issues that require review.

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


⚠️ Analysis Unavailable

We ran into an issue on our side and couldn’t complete the review right now

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Preview feature that displays additional code issues based on a deep analysis of related PRs and wider repository context

Action Required (3)

1. Critical Logic Error in PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost

Root cause

In the newly created PrismaOrgMembershipRepository.ts file, the isLoggedInUserOrgAdminOfBookingHost method has a critical bug on line 27. The condition checks if (orgIdsWhereLoggedInUserAdmin.length > 0) and returns false, which is inverted logic. This means when an org admin (who would have org IDs in the array) tries to perform booking operations, the method immediately returns false, denying access. The correct logic should be if (orgIdsWhereLoggedInUserAdmin.length === 0) or if (orgIdsWhereLoggedInUserAdmin.length <= 0). This bug affects multiple critical booking operations including canceling bookings (handleCancelBooking.ts line 147), rescheduling seated bookings (rescheduleSeatedBooking.ts line 101), and confirming bookings (confirm.handler.ts line 476). The inverted logic will prevent org admins from managing bookings for their organization members, which is the opposite of the intended feature being added in this PR.


Code Reference

File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts

static async isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number) {
    const orgIdsWhereLoggedInUserAdmin = await this.getOrgIdsWhereAdmin(loggedInUserId);

    if (orgIdsWhereLoggedInUserAdmin.length > 0) {
      return false;
    }

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The `isLoggedInUserOrgAdminOfBookingHost` method in `PrismaOrgMembershipRepository` has inverted logic that causes it to return false when the logged-in user IS an org admin, which is the opposite of the intended behavior.

## Context
This method is used to authorize org admins to manage bookings (cancel, reschedule, confirm) for users in their organization. The current logic returns false when orgIdsWhereLoggedInUserAdmin has items, which means actual org admins are denied access.

## Recommended Files to Fix
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[24-29]

## Fix Instructions
In the file `packages/lib/server/repository/PrismaOrgMembershipRepository.ts`, change line 27 from:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
  return false;
}
```
to:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length === 0) {
  return false;
}
```

This ensures that when a user has NO org admin memberships (length === 0), the method returns false early. When they DO have org admin memberships, the method continues to check if the booking user is in one of those organizations.
2. Incorrect Return Logic in PrismaOrgMembershipRepository Line 46

Root cause

In the isLoggedInUserOrgAdminOfBookingHost method at line 46, the code returns true when bookingUserOrgMembership is null/undefined (if (!bookingUserOrgMembership) return true;). This is backwards - if the booking user is NOT a member of any organization where the logged-in user is an admin, the method should return false (no authorization), not true. This logic error, combined with the error on line 27, creates a double-negative situation that will cause incorrect authorization decisions. When the booking user is not in the admin's organization, access should be denied, not granted.


Code Reference

File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts

if (!bookingUserOrgMembership) return true;

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
Line 46 in `PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost` has inverted return logic. When the booking user is NOT found in the admin's organization, it returns true (granting access), when it should return false (denying access).

## Context
The method queries for a membership record of the booking user in organizations where the logged-in user is an admin. If no such membership is found, it means the booking user is not in the admin's organization, so the admin should NOT have authorization to manage their bookings.

## Recommended Files to Fix
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[46]

## Fix Instructions
In the file `packages/lib/server/repository/PrismaOrgMembershipRepository.ts`, change line 46 from:
```typescript
if (!bookingUserOrgMembership) return true;
```
to:
```typescript
if (!bookingUserOrgMembership) return false;
```

This ensures that when the booking user is not a member of any organization where the logged-in user is an admin, the authorization check correctly returns false.
3. Incorrect Authorization Logic in handleCancelBooking.ts

Root cause

In the handleCancelBooking.ts file at line 155, the authorization check uses if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) to throw an unauthorized error. This logic is backwards - the condition should throw an error when the user is NOT an org admin (using !userIsOrgAdminOfBookingUser), not when they ARE an org admin. The current logic will deny access to org admins who should be authorized to cancel bookings for users in their organization. The correct condition should be if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) to only throw the error when none of the authorization conditions are met.


Code Reference

File: packages/features/bookings/lib/handleCancelBooking.ts

const userIsOrgAdminOfBookingUser =
      userId &&
      bookingToDelete.userId &&
      (await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
        userId,
        bookingToDelete.userId
      ));

    if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
      throw new HttpError({
        statusCode: 401,
        message: "User not a host of this event or an admin of the booking user",
      });
    }

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The authorization check in handleCancelBooking.ts has inverted logic. It throws an unauthorized error when the user IS an org admin, when it should throw the error when the user is NOT an org admin.

## Context
This PR adds the ability for org admins to cancel bookings for users in their organization. The authorization check should allow access if the user is a host, owner, OR org admin. Currently it denies access when the user IS an org admin.

## Recommended Files to Fix
- packages/features/bookings/lib/handleCancelBooking.ts[155-159]

## Fix Instructions
In the file `packages/features/bookings/lib/handleCancelBooking.ts`, change line 155 from:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
```
to:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
```

This ensures that the error is only thrown when the user is NOT a host, NOT an owner, AND NOT an org admin of the booking user.

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Preview feature that displays additional code issues based on a deep analysis of related PRs and wider repository context

Action Required (2)

1. Inverted Logic in Org Admin Check - Always Returns False

Root cause

The newly created PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost method contains a critical logic error. On line 27, the code checks if (orgIdsWhereLoggedInUserAdmin.length > 0) return false;. This means when a user IS an admin of organizations (length > 0), the function immediately returns false, indicating they are NOT an admin. This is the opposite of the intended behavior. The function should return false when the length is 0 (user is not an admin of any orgs). This breaks all org admin authorization checks for booking operations (reschedule, cancel, confirm) across the entire application, as org admins will be denied access even when they should have permissions.


Code Reference

File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts

+  static async isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number) {
+    const orgIdsWhereLoggedInUserAdmin = await this.getOrgIdsWhereAdmin(loggedInUserId);
+
+    if (orgIdsWhereLoggedInUserAdmin.length > 0) {
+      return false;
+    }

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The `isLoggedInUserOrgAdminOfBookingHost` method has inverted logic that causes it to return false when a user IS an org admin, instead of when they are NOT an org admin.

## Context
This method is used to check if a logged-in user is an org admin of the booking host user. It should return true if the user has admin permissions, false otherwise.

## Recommended Fix
In file `packages/lib/server/repository/PrismaOrgMembershipRepository.ts` at line 27, change the condition:

**Current (incorrect):**
```typescript
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
  return false;
}
```

**Should be:**
```typescript
if (orgIdsWhereLoggedInUserAdmin.length === 0) {
  return false;
}
```

This ensures the function returns false early only when the user is NOT an admin of any organizations.

## Files to Fix
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-29]
2. Incorrect Boolean Logic in Cancel Booking Authorization

Root cause

In the handleCancelBooking.ts file at line 156, the authorization logic uses && userIsOrgAdminOfBookingUser instead of || userIsOrgAdminOfBookingUser. The condition checks if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) and throws an unauthorized error. This is incorrect because if the user IS an org admin (userIsOrgAdminOfBookingUser is true), they should be ALLOWED to cancel the booking, not denied. The logic should use || to check if the user is NEITHER a host NOR an owner NOR an org admin, and only then throw the error. With the current && logic, org admins who have proper permissions will be incorrectly denied access.


Code Reference

File: packages/features/bookings/lib/handleCancelBooking.ts

+    const userIsOrgAdminOfBookingUser =
+      userId &&
+      bookingToDelete.userId &&
+      (await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
+        userId,
+        bookingToDelete.userId
+      ));
+
+    if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
+      throw new HttpError({
+        statusCode: 401,
+        message: "User not a host of this event or an admin of the booking user",
+      });
+    }

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The authorization check for canceling seated bookings has incorrect boolean logic. It throws an unauthorized error when the user IS an org admin, instead of when they are NOT an org admin.

## Context
The code checks if a user has permission to cancel a seated booking. Users should be allowed if they are a host, owner of the event type, OR an org admin of the booking user. The current logic incorrectly denies access to org admins.

## Recommended Fix
In file `packages/features/bookings/lib/handleCancelBooking.ts` at line 156, change the condition:

**Current (incorrect):**
```typescript
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
  throw new HttpError({
    statusCode: 401,
    message: "User not a host of this event or an admin of the booking user",
  });
}
```

**Should be:**
```typescript
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
  throw new HttpError({
    statusCode: 401,
    message: "User not a host of this event or an admin of the booking user",
  });
}
```

This ensures the error is thrown only when the user lacks ALL three permissions (not a host, not an owner, and not an org admin).

## Files to Fix
- packages/features/bookings/lib/handleCancelBooking.ts[156-161]

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)


⚠️ Analysis Unavailable

We ran into an issue on our side and couldn’t complete the review right now

@tomerqodo

tomerqodo commented Nov 12, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Preview feature that displays additional code issues based on a deep analysis of related PRs and wider repository context

🛑 Action Required (4)

1. Critical Logic Error: Inverted Return Value in Org Membership Check

Root cause

Line 46 of PrismaOrgMembershipRepository returns true when bookingUserOrgMembership is not found, but should return false. This grants unauthorized users access to booking management operations, creating a critical security vulnerability where non-org-admins can manage bookings they shouldn't have access to.


Code Reference

File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts

+    if (!bookingUserOrgMembership) return true;

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue:** Critical security vulnerability - inverted return value grants unauthorized access

**Context:** The isLoggedInUserOrgAdminOfBookingHost method checks if a booking user is a member of an org where the logged-in user is admin. When no membership is found, it incorrectly returns true, granting unauthorized access.

**Recommended files to fix:**
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[46-46]

**Fix:** Change line 46 from `if (!bookingUserOrgMembership) return true;` to `if (!bookingUserOrgMembership) return false;`. When the booking user is not a member of any org where the logged-in user is admin, the logged-in user should NOT be considered an org admin of the booking user.
2. Critical Logic Error: Early Return Condition Inverted in Org Admin Check

Root cause

In PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost, line 27 returns false when orgIdsWhereLoggedInUserAdmin.length > 0, but should return false when length === 0. This inverted logic prevents any org admin from being recognized, breaking all org admin booking management features.


Code Reference

File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts

+    if (orgIdsWhereLoggedInUserAdmin.length > 0) {
+      return false;
+    }

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue:** Critical logic error in org admin authorization check

**Context:** The isLoggedInUserOrgAdminOfBookingHost method is checking if a logged-in user is an org admin of a booking host. The early return condition is inverted, causing all org admins to be denied authorization.

**Recommended files to fix:**
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-29]

**Fix:** Change line 27 from `if (orgIdsWhereLoggedInUserAdmin.length > 0) {` to `if (orgIdsWhereLoggedInUserAdmin.length === 0) {`. The logic should return false when the user is NOT an admin of any org (length === 0), not when they ARE an admin (length > 0).
3. Critical Logic Error: Missing NOT Operator in Cancel Booking Authorization

Root cause

Line 156 in handleCancelBooking.ts is missing a NOT operator before userIsOrgAdminOfBookingUser. The current logic throws a 401 error when the user IS an org admin (and not a host/owner), which is backwards. This prevents authorized org admins from canceling seated bookings.


Code Reference

File: packages/features/bookings/lib/handleCancelBooking.ts

+    if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
+      throw new HttpError({
+        statusCode: 401,
+        message: "User not a host of this event or an admin of the booking user",
+      });
+    }

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue:** Missing NOT operator in authorization check prevents org admins from canceling bookings

**Context:** The handleCancelBooking function checks if a user is authorized to cancel a seated booking. The condition should throw an error when the user lacks all three authorizations (not host, not owner, not org admin), but currently throws when they ARE an org admin.

**Recommended files to fix:**
- packages/features/bookings/lib/handleCancelBooking.ts[156-161]

**Fix:** Change line 156 from `if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {` to `if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {`. Add the NOT operator (!) before userIsOrgAdminOfBookingUser so the error is thrown when the user is NOT authorized, not when they ARE authorized.
4. Critical Bug: Swapped Parameters in Org Admin Authorization Check

Root cause

In bookings.service.ts line 894-896, the parameters are swapped when calling isLoggedInUserOrgAdminOfBookingHost. The method expects (loggedInUserId, bookingUserId) but receives (bookingUserId, authUserId), causing the authorization check to evaluate if the booking user is an admin of the logged-in user instead of vice versa.


Code Reference

File: apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts

+    const isOrgAdmin = await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
+      bookingUserId,
+      authUserId
+    );

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue:** Parameters passed in wrong order to authorization check method

**Context:** The isIndividualSeatOrOrgAdminReschedule method calls isLoggedInUserOrgAdminOfBookingHost to check if the logged-in user is an org admin of the booking user. The parameters are currently swapped, causing the check to evaluate backwards.

**Recommended files to fix:**
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[894-897]

**Fix:** Swap the parameters on lines 895-896. Change from `bookingUserId, authUserId` to `authUserId, bookingUserId`. The method signature is `isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number)`, so authUserId should be first and bookingUserId should be second.

},
});

if (!bookingUserOrgMembership) return true;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[breaking-issue] [Critical Logic Error: Inverted Return Value in Org Membership Check]
Line 46 of PrismaOrgMembershipRepository returns true when bookingUserOrgMembership is not found, but should return false. This grants unauthorized users access to booking management operations, creating a critical security vulnerability where non-org-admins can manage bookings they shouldn't have access to.

>� Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue:** Critical security vulnerability - inverted return value grants unauthorized access

**Context:** The isLoggedInUserOrgAdminOfBookingHost method checks if a booking user is a member of an org where the logged-in user is admin. When no membership is found, it incorrectly returns true, granting unauthorized access.

**Recommended files to fix:**
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[46-46]

**Fix:** Change line 46 from `if (!bookingUserOrgMembership) return true;` to `if (!bookingUserOrgMembership) return false;`. When the booking user is not a member of any org where the logged-in user is admin, the logged-in user should NOT be considered an org admin of the booking user.

Comment on lines +27 to +29
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
return false;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[breaking-issue] [Critical Logic Error: Early Return Condition Inverted in Org Admin Check]
In PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost, line 27 returns false when orgIdsWhereLoggedInUserAdmin.length > 0, but should return false when length === 0. This inverted logic prevents any org admin from being recognized, breaking all org admin booking management features.

>� Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue:** Critical logic error in org admin authorization check

**Context:** The isLoggedInUserOrgAdminOfBookingHost method is checking if a logged-in user is an org admin of a booking host. The early return condition is inverted, causing all org admins to be denied authorization.

**Recommended files to fix:**
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-29]

**Fix:** Change line 27 from `if (orgIdsWhereLoggedInUserAdmin.length > 0) {` to `if (orgIdsWhereLoggedInUserAdmin.length === 0) {`. The logic should return false when the user is NOT an admin of any org (length === 0), not when they ARE an admin (length > 0).

Comment on lines +156 to +160
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
throw new HttpError({
statusCode: 401,
message: "User not a host of this event or an admin of the booking user",
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[breaking-issue] [Critical Logic Error: Missing NOT Operator in Cancel Booking Authorization]
Line 156 in handleCancelBooking.ts is missing a NOT operator before userIsOrgAdminOfBookingUser. The current logic throws a 401 error when the user IS an org admin (and not a host/owner), which is backwards. This prevents authorized org admins from canceling seated bookings.

>� Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue:** Missing NOT operator in authorization check prevents org admins from canceling bookings

**Context:** The handleCancelBooking function checks if a user is authorized to cancel a seated booking. The condition should throw an error when the user lacks all three authorizations (not host, not owner, not org admin), but currently throws when they ARE an org admin.

**Recommended files to fix:**
- packages/features/bookings/lib/handleCancelBooking.ts[156-161]

**Fix:** Change line 156 from `if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {` to `if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {`. Add the NOT operator (!) before userIsOrgAdminOfBookingUser so the error is thrown when the user is NOT authorized, not when they ARE authorized.

Comment on lines +894 to +897
const isOrgAdmin = await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
bookingUserId,
authUserId
);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[breaking-issue] [Critical Bug: Swapped Parameters in Org Admin Authorization Check]
In bookings.service.ts line 894-896, the parameters are swapped when calling isLoggedInUserOrgAdminOfBookingHost. The method expects (loggedInUserId, bookingUserId) but receives (bookingUserId, authUserId), causing the authorization check to evaluate if the booking user is an admin of the logged-in user instead of vice versa.

>� Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue:** Parameters passed in wrong order to authorization check method

**Context:** The isIndividualSeatOrOrgAdminReschedule method calls isLoggedInUserOrgAdminOfBookingHost to check if the logged-in user is an org admin of the booking user. The parameters are currently swapped, causing the check to evaluate backwards.

**Recommended files to fix:**
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[894-897]

**Fix:** Swap the parameters on lines 895-896. Change from `bookingUserId, authUserId` to `authUserId, bookingUserId`. The method signature is `isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number)`, so authUserId should be first and bookingUserId should be second.

@tomerqodo

tomerqodo commented Nov 13, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Preview feature that displays additional code issues based on a deep analysis of related PRs and wider repository context

},
});

if (!bookingUserOrgMembership) return true;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Return Value in Membership Check]
Line 46 returns true when bookingUserOrgMembership is null/undefined, meaning the booking user is NOT a member of any org where the logged-in user is admin. This should return false instead, as it means the logged-in user is NOT an org admin of the booking host.

>� Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue**: Security vulnerability - function returns true when it should return false, granting unauthorized access.

**Context**: When bookingUserOrgMembership is null/undefined, it means the booking user is not a member of any org where the logged-in user is admin. This should result in returning false (no authorization), not true.

**Recommended files to fix**:
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[46-46]

**Fix**: Change line 46 from `if (!bookingUserOrgMembership) return true;` to `if (!bookingUserOrgMembership) return false;`. This ensures unauthorized users are correctly denied access.

Comment on lines +894 to +897
const isOrgAdmin = await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
bookingUserId,
authUserId
);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Swapped Parameters in Org Admin Function Call]
The call to isLoggedInUserOrgAdminOfBookingHost at lines 894-896 passes bookingUserId as the first parameter and authUserId as the second, but the function signature expects (loggedInUserId, bookingUserId). This causes the function to check the wrong relationship.

>� Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue**: Parameters passed in wrong order to isLoggedInUserOrgAdminOfBookingHost, causing incorrect authorization checks.

**Context**: The function signature is isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number), but the call passes (bookingUserId, authUserId) which is backwards.

**Recommended files to fix**:
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[894-897]

**Fix**: Swap the parameters at lines 895-896 to pass authUserId as the first parameter and bookingUserId as the second parameter. Change from `isLoggedInUserOrgAdminOfBookingHost(bookingUserId, authUserId)` to `isLoggedInUserOrgAdminOfBookingHost(authUserId, bookingUserId)`.

Comment on lines +156 to +160
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
throw new HttpError({
statusCode: 401,
message: "User not a host of this event or an admin of the booking user",
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Authorization Logic in Cancel Booking]
Line 156 throws a 401 error when userIsOrgAdminOfBookingUser is true, but should throw when it's false. The condition should check if the user is NOT a host AND NOT an owner AND NOT an org admin before denying access.

>� Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue**: Inverted authorization logic throws 401 error when user IS an org admin instead of when they are NOT.

**Context**: The condition should deny access only when the user lacks all three authorizations: not a host, not an owner, and not an org admin. Currently it denies access when the user IS an org admin.

**Recommended files to fix**:
- packages/features/bookings/lib/handleCancelBooking.ts[156-161]

**Fix**: Add the NOT operator to userIsOrgAdminOfBookingUser in the condition at line 156. Change from `if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser)` to `if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser)`. This ensures the error is thrown only when the user lacks all three authorizations.

Comment on lines +27 to +29
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
return false;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Early Return Logic in Org Admin Check]
The condition at line 27 checks if orgIdsWhereLoggedInUserAdmin.length > 0 and returns false, which is backwards. When the length is greater than 0, it means the user IS an admin and should continue checking, not return false immediately.

>� Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
**Issue**: Inverted logic in org admin check causes function to return false when user IS an admin.

**Context**: The isLoggedInUserOrgAdminOfBookingHost function should return true if the logged-in user is an org admin of the booking host. The early return at line 27-29 should only trigger when the user is NOT an admin of any org.

**Recommended files to fix**:
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-29]

**Fix**: Change line 27 from `if (orgIdsWhereLoggedInUserAdmin.length > 0)` to `if (orgIdsWhereLoggedInUserAdmin.length === 0)`. This ensures the function returns false early only when the user is not an admin of any organization, and continues checking when they are an admin.

@tomerqodo

tomerqodo commented Nov 13, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Preview feature that displays additional code issues based on a deep analysis of related PRs and wider repository context

},
});

if (!bookingUserOrgMembership) return true;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Return Value for Missing Membership]
At line 46 of PrismaOrgMembershipRepository, when bookingUserOrgMembership is not found, the function returns true. This grants org admin privileges to users who should not have them, creating a security vulnerability.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue
Line 46 in packages/lib/server/repository/PrismaOrgMembershipRepository.ts[46-46] returns true when the booking user is NOT found in any org where the logged-in user is admin. This is a security vulnerability.

## Context
The function should return true only when the logged-in user IS an org admin of the booking host. If the booking user is not a member of any organization where the logged-in user is admin, the function should return false to deny access.

## Fix
Change line 46 from:
```typescript
if (!bookingUserOrgMembership) return true;
```
to:
```typescript
if (!bookingUserOrgMembership) return false;
```

## Files to Fix
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[46-46]

Comment on lines +27 to +29
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
return false;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Logic in Org Admin Check]
The isLoggedInUserOrgAdminOfBookingHost function has inverted logic at line 27-28. When orgIdsWhereLoggedInUserAdmin.length > 0 (user IS an admin), it returns false. This prevents org admins from managing bookings.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue
The condition at line 27 in packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-29] is inverted. It returns false when the user IS an org admin.

## Context
The function isLoggedInUserOrgAdminOfBookingHost should return true if the logged-in user is an org admin of the booking host's organization. The early return should only happen when the user is NOT an admin of any org.

## Fix
Change line 27 from:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
```
to:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length === 0) {
```

## Files to Fix
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-27]

Comment on lines +156 to +160
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
throw new HttpError({
statusCode: 401,
message: "User not a host of this event or an admin of the booking user",
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Incorrect Authorization Logic in Cancel Booking]
In handleCancelBooking.ts line 156, the condition throws an error when userIsOrgAdminOfBookingUser is true. This blocks org admins from canceling seated bookings, which contradicts the feature's purpose and will cause the e2e test to fail.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue
Line 156 in packages/features/bookings/lib/handleCancelBooking.ts[156-161] throws an error when the user IS an org admin, blocking legitimate cancellations.

## Context
The authorization check should allow org admins to cancel seated bookings for their organization members. The error should only be thrown when the user is NOT a host, NOT an owner, AND NOT an org admin. The similar logic in rescheduleSeatedBooking.ts:111 correctly uses '!isOrgAdmin'.

## Fix
Change line 156 from:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
```
to:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
```

## Files to Fix
- packages/features/bookings/lib/handleCancelBooking.ts[156-156]

Comment on lines +894 to +897
const isOrgAdmin = await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
bookingUserId,
authUserId
);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Swapped Parameters in Org Admin Check]
In bookings.service.ts lines 894-896, the parameters to isLoggedInUserOrgAdminOfBookingHost are swapped. It passes bookingUserId first and authUserId second, but the function expects loggedInUserId first. This checks the wrong authorization relationship.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue
Lines 894-896 in apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[894-897] pass parameters in the wrong order to isLoggedInUserOrgAdminOfBookingHost.

## Context
The function signature is isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number). The first parameter should be the logged-in user (authUserId) and the second should be the booking user (bookingUserId). All other call sites in the codebase pass parameters correctly.

## Fix
Change lines 894-896 from:
```typescript
const isOrgAdmin = await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
  bookingUserId,
  authUserId
);
```
to:
```typescript
const isOrgAdmin = await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
  authUserId,
  bookingUserId
);
```

## Files to Fix
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[894-897]

@tomerqodo

tomerqodo commented Nov 13, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Preview feature that displays additional code issues based on a deep analysis of related PRs and wider repository context

Comment on lines +24 to +29
static async isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number) {
const orgIdsWhereLoggedInUserAdmin = await this.getOrgIdsWhereAdmin(loggedInUserId);

if (orgIdsWhereLoggedInUserAdmin.length > 0) {
return false;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Logic in Org Admin Check]
The function checks if orgIdsWhereLoggedInUserAdmin.length > 0 and returns false, but this is backwards. When the logged-in user IS an admin of organizations (length > 0), the function should continue checking if the booking user belongs to those orgs, not return false immediately.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The logic in PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost is inverted, causing it to return false for actual org admins.

## Context
This function checks if a logged-in user is an org admin of a booking host. It should return false only when the user has NO admin organizations, but currently returns false when they DO have admin organizations.

## Recommended Fix
File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-28]

Change line 27 from:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
```

To:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length === 0) {
```

This ensures the function only returns false when the user has no admin organizations, allowing the subsequent logic to check if the booking user belongs to those organizations.

Comment on lines +148 to +160
const userIsOrgAdminOfBookingUser =
userId &&
bookingToDelete.userId &&
(await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
userId,
bookingToDelete.userId
));

if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
throw new HttpError({
statusCode: 401,
message: "User not a host of this event or an admin of the booking user",
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Incorrect Boolean Logic in Cancel Authorization]
Line 156 in handleCancelBooking.ts checks '!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser' which requires the user to be an org admin AND not a host AND not an owner to pass. This should use OR logic to allow any of these roles to cancel.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The authorization check in handleCancelBooking.ts has incorrect boolean logic that prevents org admins from canceling bookings.

## Context
The code should allow users who are hosts, owners, OR org admins to cancel bookings. Currently it throws an error when the user IS an org admin (and not a host/owner), which is backwards.

## Recommended Fix
File: packages/features/bookings/lib/handleCancelBooking.ts[156-161]

Change line 156 from:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
```

To:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
```

This ensures the error is only thrown when the user is NONE of the authorized roles (not a host, not an owner, and not an org admin).

@tomerqodo

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Come back soon, analysis in progress

Comment on lines +31 to +46
const bookingUserOrgMembership = await prisma.membership.findFirst({
where: {
userId: bookingUserId,
teamId: {
in: orgIdsWhereLoggedInUserAdmin,
},
team: {
parentId: null,
},
},
select: {
userId: true,
},
});

if (!bookingUserOrgMembership) return true;

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Return Logic After Membership Check]
In isLoggedInUserOrgAdminOfBookingHost, line 46 returns true when bookingUserOrgMembership is null/not found. This is inverted - if the booking user is NOT a member of the org, the logged-in user should NOT be authorized as their org admin. The function should return false when no membership is found.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
Line 46 in `isLoggedInUserOrgAdminOfBookingHost` returns `true` when the booking user is NOT found as a member of the org, which grants unauthorized access.

## Context
This function should only return true if the booking user IS a member of an organization where the logged-in user is an admin. If no membership is found, authorization should be denied.

## Recommended Fix
Modify the file: `packages/lib/server/repository/PrismaOrgMembershipRepository.ts`

**Line 46**: Change from:
```typescript
if (!bookingUserOrgMembership) return true;
```

To:
```typescript
if (!bookingUserOrgMembership) return false;
```

This ensures authorization is denied when the booking user is not a member of any org where the logged-in user is an admin.

Comment on lines +24 to +29
static async isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number) {
const orgIdsWhereLoggedInUserAdmin = await this.getOrgIdsWhereAdmin(loggedInUserId);

if (orgIdsWhereLoggedInUserAdmin.length > 0) {
return false;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Logic in Org Admin Check]
The isLoggedInUserOrgAdminOfBookingHost method has inverted logic on line 27-28. It returns false when orgIdsWhereLoggedInUserAdmin.length > 0, which is backwards - it should return false when the length is 0 (no admin memberships). This causes the function to fail immediately for all legitimate org admins.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The `isLoggedInUserOrgAdminOfBookingHost` method in `PrismaOrgMembershipRepository` has inverted logic that causes it to return `false` when org admin memberships ARE found, when it should return `false` when NO memberships are found.

## Context
This function is used to authorize org admins to manage bookings for users in their organization. The current logic breaks all authorization checks.

## Recommended Fix
Modify the file: `packages/lib/server/repository/PrismaOrgMembershipRepository.ts`

**Line 27**: Change the condition from:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
```

To:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length === 0) {
```

This ensures the function returns `false` early only when the logged-in user has NO org admin memberships, and continues to check if the booking user belongs to those orgs when memberships exist.

Comment on lines +148 to +160
const userIsOrgAdminOfBookingUser =
userId &&
bookingToDelete.userId &&
(await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
userId,
bookingToDelete.userId
));

if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
throw new HttpError({
statusCode: 401,
message: "User not a host of this event or an admin of the booking user",
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Incorrect Authorization Logic in Cancel Booking]
In handleCancelBooking.ts, the authorization check on line 155 uses && instead of || in the condition, causing it to throw an error when the user IS an org admin of the booking user, which is backwards. The condition should use || to throw an error when the user is NOT a host AND NOT an owner AND NOT an org admin.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The authorization check in `handleCancelBooking` has incorrect logic that blocks org admins instead of allowing them to cancel bookings.

## Context
The PR adds org admin authorization for canceling bookings. The condition should throw an error when the user is NOT a host AND NOT an owner AND NOT an org admin.

## Recommended Fix
Modify the file: `packages/features/bookings/lib/handleCancelBooking.ts`

**Line 155**: Change from:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
```

To:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
```

Add the negation operator `!` before `userIsOrgAdminOfBookingUser` to correctly allow org admins to cancel bookings.

@tomerqodo

tomerqodo commented Nov 13, 2025

Copy link
Copy Markdown
Author

Agentic Code Suggestions (Beta)

Preview feature that displays additional code issues based on a deep analysis of related PRs and wider repository context

🛑 Action Required (2)

1. Inverted Logic in Org Admin Check

Root cause

In PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost, line 27 checks if orgIdsWhereLoggedInUserAdmin.length > 0 and returns false. This is inverted logic - if the logged-in user IS an admin of organizations (length > 0), the function should continue checking, not return false immediately.


Code Reference

File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts

+  static async isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number) {
+    const orgIdsWhereLoggedInUserAdmin = await this.getOrgIdsWhereAdmin(loggedInUserId);
+
+    if (orgIdsWhereLoggedInUserAdmin.length > 0) {
+      return false;
+    }

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The authorization check in `PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost` has inverted logic that prevents org admins from managing bookings.

## Context
The method should return true if the logged-in user is an org admin of the booking host's organization. Currently, it returns false when the user IS an admin (length > 0), which is backwards.

## Recommended Fix
File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-28]

Change line 27 from:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
```

To:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length === 0) {
```

This ensures the method returns false only when the user is NOT an admin of any organizations.
2. Incorrect Authorization Logic in Cancel Booking

Root cause

In handleCancelBooking.ts line 156, the authorization check uses !userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser which throws an error when the user IS an org admin. The logic should allow org admins, not block them.


Code Reference

File: packages/features/bookings/lib/handleCancelBooking.ts

+    if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
+      throw new HttpError({
+        statusCode: 401,
+        message: "User not a host of this event or an admin of the booking user",
+      });
+    }

Agent Prompt

Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The authorization check in `handleCancelBooking.ts` incorrectly blocks org admins from canceling bookings instead of allowing them.

## Context
The PR adds functionality for org admins to cancel bookings for managed users. The authorization check should allow users who are hosts, owners, OR org admins. Currently, it throws an error when the user IS an org admin.

## Recommended Fix
File: packages/features/bookings/lib/handleCancelBooking.ts[156-161]

Change line 156 from:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
```

To:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
```

This ensures the error is thrown only when the user is NOT a host AND NOT an owner AND NOT an org admin, allowing org admins to proceed with cancellation.

Comment on lines +24 to +29
static async isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number) {
const orgIdsWhereLoggedInUserAdmin = await this.getOrgIdsWhereAdmin(loggedInUserId);

if (orgIdsWhereLoggedInUserAdmin.length > 0) {
return false;
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Inverted Logic in Org Admin Check]
In PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost, line 27 checks if orgIdsWhereLoggedInUserAdmin.length > 0 and returns false. This is inverted logic - if the logged-in user IS an admin of organizations (length > 0), the function should continue checking, not return false immediately.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The authorization check in `PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost` has inverted logic that prevents org admins from managing bookings.

## Context
The method should return true if the logged-in user is an org admin of the booking host's organization. Currently, it returns false when the user IS an admin (length > 0), which is backwards.

## Recommended Fix
File: packages/lib/server/repository/PrismaOrgMembershipRepository.ts[27-28]

Change line 27 from:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length > 0) {
```

To:
```typescript
if (orgIdsWhereLoggedInUserAdmin.length === 0) {
```

This ensures the method returns false only when the user is NOT an admin of any organizations.

Comment on lines +156 to +160
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
throw new HttpError({
statusCode: 401,
message: "User not a host of this event or an admin of the booking user",
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[action-required] [Incorrect Authorization Logic in Cancel Booking]
In handleCancelBooking.ts line 156, the authorization check uses !userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser which throws an error when the user IS an org admin. The logic should allow org admins, not block them.

>Agent Prompt
Copy this prompt and use it to remediate the issue with your preferred AI generation tools
## Issue Description
The authorization check in `handleCancelBooking.ts` incorrectly blocks org admins from canceling bookings instead of allowing them.

## Context
The PR adds functionality for org admins to cancel bookings for managed users. The authorization check should allow users who are hosts, owners, OR org admins. Currently, it throws an error when the user IS an org admin.

## Recommended Fix
File: packages/features/bookings/lib/handleCancelBooking.ts[156-161]

Change line 156 from:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
```

To:
```typescript
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
```

This ensures the error is thrown only when the user is NOT a host AND NOT an owner AND NOT an org admin, allowing org admins to proceed with cancellation.

@ofir-frd

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (5) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Org admin check inverted 🐞 Bug ⛨ Security
Description
PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost returns false when the user
has org-admin orgIds and can return true when they have none, which can incorrectly grant
org-admin authorization to non-admin users across confirm/reschedule/cancel flows.
Code

packages/lib/server/repository/PrismaOrgMembershipRepository.ts[R24-47]

+  static async isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number) {
+    const orgIdsWhereLoggedInUserAdmin = await this.getOrgIdsWhereAdmin(loggedInUserId);
+
+    if (orgIdsWhereLoggedInUserAdmin.length > 0) {
+      return false;
+    }
+
+    const bookingUserOrgMembership = await prisma.membership.findFirst({
+      where: {
+        userId: bookingUserId,
+        teamId: {
+          in: orgIdsWhereLoggedInUserAdmin,
+        },
+        team: {
+          parentId: null,
+        },
+      },
+      select: {
+        userId: true,
+      },
+    });
+
+    if (!bookingUserOrgMembership) return true;
+
Evidence
The helper’s short-circuit and membership presence checks are reversed, making authorization
decisions incorrect. Multiple authorization paths call this helper expecting true only for
legitimate org admins.

packages/lib/server/repository/PrismaOrgMembershipRepository.ts[24-60]
packages/trpc/server/routers/viewer/bookings/confirm.handler.ts[421-483]
packages/features/bookings/lib/handleSeats/reschedule/rescheduleSeatedBooking.ts[100-113]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost` has inverted boolean logic:
- It returns `false` when `orgIdsWhereLoggedInUserAdmin.length > 0` (should only short-circuit to `false` when the list is empty).
- It returns `true` when no membership is found for the booking host in those orgs.
This can deny real org admins and (worse) treat non-admin users as org admins.

### Issue Context
This helper is used for authorization decisions in booking confirmation and seated booking reschedule/cancel flows.

### Fix Focus Areas
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[24-60]

### Recommended fix
1. Change the early return to:
  - `if (orgIdsWhereLoggedInUserAdmin.length === 0) return false;`
2. Change the membership checks to return `true` only when the booking user is found in either:
  - an org team with `team.parentId: null` whose `teamId` is in `orgIdsWhereLoggedInUserAdmin`, OR
  - a sub-team whose `team.parentId` is in `orgIdsWhereLoggedInUserAdmin`.
3. Ensure the function returns `false` when neither membership exists.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Org admin args swapped 🐞 Bug ⛨ Security
Description
BookingsService_2024_08_13 calls isLoggedInUserOrgAdminOfBookingHost with `(bookingUserId,
authUserId) instead of (authUserId, bookingUserId)`, so org-admin authorization is evaluated
against the wrong identities.
Code

apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[R894-897]

+    const isOrgAdmin = await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
+      bookingUserId,
+      authUserId
+    );
Evidence
The repository signature clearly expects logged-in user first, but the service passes booking owner
first, making the org-admin check incorrect even if the repository logic were fixed.

packages/lib/server/repository/PrismaOrgMembershipRepository.ts[24-26]
apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[877-900]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost` is defined as `(loggedInUserId, bookingUserId)` but is called with reversed arguments in `BookingsService_2024_08_13`, leading to incorrect authorization decisions.

### Issue Context
This is used to determine whether a seated booking reschedule should be allowed for an org admin.

### Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[877-900]

### Recommended fix
Call:
```ts
await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(authUserId, bookingUserId)
```
(not the reversed order).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Seat reschedule routing broken 🐞 Bug ≡ Correctness
Description
For seated reschedules where seatUid is present, createRescheduleBookingRequest routes the
request to transformInputRescheduleBooking (non-seat path) because of a negated condition, causing
individual-seat reschedules to fail with the “seatUid required” error.
Code

apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts[R513-516]

+    const bodyTransformed =
+      !isIndividualSeatReschedule && "seatUid" in body
+        ? await this.transformInputRescheduleSeatedBooking(bookingUid, body)
+        : await this.transformInputRescheduleBooking(bookingUid, body, isIndividualSeatReschedule);
Evidence
The code negates isIndividualSeatReschedule when deciding whether to run the seated transformer,
while the booking service sets that boolean to true for seatUid requests; the non-seated transformer
then contains the seated-booking rejection logic.

apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[760-779]
apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts[507-517]
apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts[611-632]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`createRescheduleBookingRequest` uses:
```ts
!isIndividualSeatReschedule && "seatUid" in body
 ? transformInputRescheduleSeatedBooking(...)
 : transformInputRescheduleBooking(...)
```
This makes the seated transformer *unreachable* precisely when `seatUid` exists (the individual-seat case), which then drives seated requests into `transformInputRescheduleBooking` where they can throw the seated-booking error.

### Issue Context
`BookingsService_2024_08_13` sets the boolean to `true` when the body contains `seatUid`, so the negation breaks the intended branch.

### Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts[507-517]
- apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts[611-632]
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[760-779]

### Recommended fix
1. Select the transformer based primarily on the presence of `seatUid`:
  - if `"seatUid" in body` -> `transformInputRescheduleSeatedBooking`
  - else -> `transformInputRescheduleBooking`
2. If you need to support org-admin “all seats” reschedule, use a separate boolean (e.g. `isOrgAdminAllSeatsReschedule`) and apply it only to the seated-booking validation (not to transformer selection).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. Cancel auth condition inverted 🐞 Bug ≡ Correctness
Description
handleCancelBooking throws 401 when userIsOrgAdminOfBookingUser is true, which blocks org admins
from cancelling seated bookings (all seats) once the org-admin check is corrected.
Code

packages/features/bookings/lib/handleCancelBooking.ts[R148-160]

+    const userIsOrgAdminOfBookingUser =
+      userId &&
+      bookingToDelete.userId &&
+      (await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
+        userId,
+        bookingToDelete.userId
+      ));
+
+    if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
+      throw new HttpError({
+        statusCode: 401,
+        message: "User not a host of this event or an admin of the booking user",
+      });
Evidence
The condition currently throws only when the org-admin predicate is true, contradicting the intended
authorization (“allow org admin”).

packages/features/bookings/lib/handleCancelBooking.ts[140-162]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The seated-booking cancellation guard is inverted:
```ts
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) throw 401;
```
This throws *because* the user is an org admin, rather than when they are not.

### Issue Context
This block runs when cancelling a seated booking without `seatReferenceUid` (i.e., cancelling all seats).

### Fix Focus Areas
- packages/features/bookings/lib/handleCancelBooking.ts[140-162]

### Recommended fix
Change the condition to:
```ts
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
 throw new HttpError({ statusCode: 401, message: ... });
}
```

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Org admin reschedule GET denied 🐞 Bug ≡ Correctness
Description
GET /v2/bookings/:bookingUid/reschedule now passes an optional authenticated user ID, but
getBookingForReschedule still only authorizes seated booking access for booking owner/host, so org
admins cannot fetch booking data needed to reschedule all seats.
Code

apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts[R179-186]

  @Get("/:bookingUid/reschedule")
-  async getBookingForReschedule(@Param("bookingUid") bookingUid: string): Promise<ApiResponse<unknown>> {
-    const booking = await getBookingForReschedule(bookingUid);
+  @UseGuards(OptionalApiAuthGuard)
+  async getBookingForReschedule(
+    @Param("bookingUid") bookingUid: string,
+    @GetOptionalUser() user: AuthOptionalUser
+  ): Promise<ApiResponse<unknown>> {
+    const booking = await getBookingForReschedule(bookingUid, user?.id);
Evidence
The controller change forwards user?.id, but the core helper’s seated-booking ownership gate
explicitly returns null unless requester is owner/host, with no org-admin path.

apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts[179-195]
packages/features/bookings/lib/get-booking.ts[183-196]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The controller now supports optional authentication and forwards `user?.id` to `getBookingForReschedule`, but the underlying seated-booking authorization gate does not recognize org admins. Org admins will still receive `null` (and thus 404) when requesting bookingUid-based seated reschedule details.

### Issue Context
This endpoint appears to be the API path for retrieving reschedule data. For seated bookings without seatUid, `getBookingForReschedule` requires the requester to be owner/host.

### Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts[179-195]
- packages/features/bookings/lib/get-booking.ts[183-196]

### Recommended fix
Extend the seated-booking authorization gate in `getBookingForReschedule` to also allow org admins (using the same org-admin check helper used elsewhere) when a `userId` is provided.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +24 to +47
static async isLoggedInUserOrgAdminOfBookingHost(loggedInUserId: number, bookingUserId: number) {
const orgIdsWhereLoggedInUserAdmin = await this.getOrgIdsWhereAdmin(loggedInUserId);

if (orgIdsWhereLoggedInUserAdmin.length > 0) {
return false;
}

const bookingUserOrgMembership = await prisma.membership.findFirst({
where: {
userId: bookingUserId,
teamId: {
in: orgIdsWhereLoggedInUserAdmin,
},
team: {
parentId: null,
},
},
select: {
userId: true,
},
});

if (!bookingUserOrgMembership) return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Org admin check inverted 🐞 Bug ⛨ Security

PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost returns false when the user
has org-admin orgIds and can return true when they have none, which can incorrectly grant
org-admin authorization to non-admin users across confirm/reschedule/cancel flows.
Agent Prompt
### Issue description
`PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost` has inverted boolean logic:
- It returns `false` when `orgIdsWhereLoggedInUserAdmin.length > 0` (should only short-circuit to `false` when the list is empty).
- It returns `true` when no membership is found for the booking host in those orgs.
This can deny real org admins and (worse) treat non-admin users as org admins.

### Issue Context
This helper is used for authorization decisions in booking confirmation and seated booking reschedule/cancel flows.

### Fix Focus Areas
- packages/lib/server/repository/PrismaOrgMembershipRepository.ts[24-60]

### Recommended fix
1. Change the early return to:
   - `if (orgIdsWhereLoggedInUserAdmin.length === 0) return false;`
2. Change the membership checks to return `true` only when the booking user is found in either:
   - an org team with `team.parentId: null` whose `teamId` is in `orgIdsWhereLoggedInUserAdmin`, OR
   - a sub-team whose `team.parentId` is in `orgIdsWhereLoggedInUserAdmin`.
3. Ensure the function returns `false` when neither membership exists.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +894 to +897
const isOrgAdmin = await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
bookingUserId,
authUserId
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Org admin args swapped 🐞 Bug ⛨ Security

BookingsService_2024_08_13 calls isLoggedInUserOrgAdminOfBookingHost with `(bookingUserId,
authUserId) instead of (authUserId, bookingUserId)`, so org-admin authorization is evaluated
against the wrong identities.
Agent Prompt
### Issue description
`PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost` is defined as `(loggedInUserId, bookingUserId)` but is called with reversed arguments in `BookingsService_2024_08_13`, leading to incorrect authorization decisions.

### Issue Context
This is used to determine whether a seated booking reschedule should be allowed for an org admin.

### Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[877-900]

### Recommended fix
Call:
```ts
await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(authUserId, bookingUserId)
```
(not the reversed order).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +513 to +516
const bodyTransformed =
!isIndividualSeatReschedule && "seatUid" in body
? await this.transformInputRescheduleSeatedBooking(bookingUid, body)
: await this.transformInputRescheduleBooking(bookingUid, body, isIndividualSeatReschedule);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Seat reschedule routing broken 🐞 Bug ≡ Correctness

For seated reschedules where seatUid is present, createRescheduleBookingRequest routes the
request to transformInputRescheduleBooking (non-seat path) because of a negated condition, causing
individual-seat reschedules to fail with the “seatUid required” error.
Agent Prompt
### Issue description
`createRescheduleBookingRequest` uses:
```ts
!isIndividualSeatReschedule && "seatUid" in body
  ? transformInputRescheduleSeatedBooking(...)
  : transformInputRescheduleBooking(...)
```
This makes the seated transformer *unreachable* precisely when `seatUid` exists (the individual-seat case), which then drives seated requests into `transformInputRescheduleBooking` where they can throw the seated-booking error.

### Issue Context
`BookingsService_2024_08_13` sets the boolean to `true` when the body contains `seatUid`, so the negation breaks the intended branch.

### Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts[507-517]
- apps/api/v2/src/ee/bookings/2024-08-13/services/input.service.ts[611-632]
- apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts[760-779]

### Recommended fix
1. Select the transformer based primarily on the presence of `seatUid`:
   - if `"seatUid" in body` -> `transformInputRescheduleSeatedBooking`
   - else -> `transformInputRescheduleBooking`
2. If you need to support org-admin “all seats” reschedule, use a separate boolean (e.g. `isOrgAdminAllSeatsReschedule`) and apply it only to the seated-booking validation (not to transformer selection).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +148 to +160
const userIsOrgAdminOfBookingUser =
userId &&
bookingToDelete.userId &&
(await PrismaOrgMembershipRepository.isLoggedInUserOrgAdminOfBookingHost(
userId,
bookingToDelete.userId
));

if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) {
throw new HttpError({
statusCode: 401,
message: "User not a host of this event or an admin of the booking user",
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. Cancel auth condition inverted 🐞 Bug ≡ Correctness

handleCancelBooking throws 401 when userIsOrgAdminOfBookingUser is true, which blocks org admins
from cancelling seated bookings (all seats) once the org-admin check is corrected.
Agent Prompt
### Issue description
The seated-booking cancellation guard is inverted:
```ts
if (!userIsHost && !userIsOwnerOfEventType && userIsOrgAdminOfBookingUser) throw 401;
```
This throws *because* the user is an org admin, rather than when they are not.

### Issue Context
This block runs when cancelling a seated booking without `seatReferenceUid` (i.e., cancelling all seats).

### Fix Focus Areas
- packages/features/bookings/lib/handleCancelBooking.ts[140-162]

### Recommended fix
Change the condition to:
```ts
if (!userIsHost && !userIsOwnerOfEventType && !userIsOrgAdminOfBookingUser) {
  throw new HttpError({ statusCode: 401, message: ... });
}
```

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 179 to 186
@Get("/:bookingUid/reschedule")
async getBookingForReschedule(@Param("bookingUid") bookingUid: string): Promise<ApiResponse<unknown>> {
const booking = await getBookingForReschedule(bookingUid);
@UseGuards(OptionalApiAuthGuard)
async getBookingForReschedule(
@Param("bookingUid") bookingUid: string,
@GetOptionalUser() user: AuthOptionalUser
): Promise<ApiResponse<unknown>> {
const booking = await getBookingForReschedule(bookingUid, user?.id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

5. Org admin reschedule get denied 🐞 Bug ≡ Correctness

GET /v2/bookings/:bookingUid/reschedule now passes an optional authenticated user ID, but
getBookingForReschedule still only authorizes seated booking access for booking owner/host, so org
admins cannot fetch booking data needed to reschedule all seats.
Agent Prompt
### Issue description
The controller now supports optional authentication and forwards `user?.id` to `getBookingForReschedule`, but the underlying seated-booking authorization gate does not recognize org admins. Org admins will still receive `null` (and thus 404) when requesting bookingUid-based seated reschedule details.

### Issue Context
This endpoint appears to be the API path for retrieving reschedule data. For seated bookings without seatUid, `getBookingForReschedule` requires the requester to be owner/host.

### Fix Focus Areas
- apps/api/v2/src/ee/bookings/2024-04-15/controllers/bookings.controller.ts[179-195]
- packages/features/bookings/lib/get-booking.ts[183-196]

### Recommended fix
Extend the seated-booking authorization gate in `getBookingForReschedule` to also allow org admins (using the same org-admin check helper used elsewhere) when a `userId` is provided.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants